/////////////////////////////////////////////////////////////////////////////
//
// CodeLib.cpp
//
// Author : L.F.
// Date   : 2006.10.24
//
/////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "CodeLib.h"

/////////////////////////////////////////////////////////////////////////////
// CCodeLib

/////////////////////////////////////////////////////////////////////////////
// CCodeLib constructor and destructor

CCodeLib::CCodeLib()
{
}

CCodeLib::~CCodeLib()
{
}

/////////////////////////////////////////////////////////////////////////////
// Implementation

void CCodeLib::UTF8ToUnicode( CString& csOut, const char* pchIn )
{
	int len=MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pchIn, -1, NULL,0);
	WCHAR * pwchOut = new WCHAR[len+1];
	memset(pwchOut, 0, len * 2 + 2);
	MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pchIn, -1, pwchOut, len);
	csOut=pwchOut;
	delete[] pwchOut;
}

void CCodeLib::UnicodeToUTF8( string& pchOut, const WCHAR* pwchIn )
{
	int len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pwchIn, -1, NULL, 0, NULL, NULL);
	char *szUtf8=new char[len + 1];
	memset(szUtf8, 0, len + 1);
	WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)pwchIn, -1, szUtf8, len, NULL,NULL);

	pchOut = szUtf8;
	delete[] szUtf8;
}


/*

void CCodeLib::UnicodeToGB2312( char* pchOut, unsigned short uData )
{
	::WideCharToMultiByte( CP_ACP, NULL, (LPCWSTR)& uData, 1, pchOut, sizeof( WCHAR ), NULL, NULL );
}

void CCodeLib::UTF8ToGB2312( std::string& strOut, const char* pchIn, int nLen )
{
	// The UTF-8 size is 3 bytes each character...
	//  note here.
	//  when It's asii code. It need to allocate more than one byte in the buffer...
/ *	char* pBuffer = new char[ nLen + 1 ];
	ZeroMemory( pBuffer, nLen );
	ASSERT( pBuffer != NULL );
	if ( pBuffer == NULL )
		return;

	char chTmp[ 4 ];
	ZeroMemory( chTmp, sizeof( chTmp ) );

	int i = 0;
	int j = 0;

	while ( i < nLen )
	{
		if ( pchIn[ i ] > 0 )
		{
			pBuffer[ j++ ] = pchIn[ i++ ];
		}
		else
		{
			WCHAR wchTmp;
			UTF8ToUnicode( & wchTmp, pchIn + i );
			UnicodeToGB2312( chTmp, wchTmp );

			pBuffer[ j     ] = chTmp[ 0 ];
			pBuffer[ j + 1 ] = chTmp[ 1 ];

			i += 3;
			j += 2;
		}
	} // End loop
	pBuffer[ j ] = '\0';
	strOut = pBuffer;

	ASSERT( pBuffer != NULL );
	delete [] pBuffer;
	* /
}

void CCodeLib::GB2312ToUTF8( std::string& strOut, const char* pchIn, int nLen )
{
	char buf[ 4 ];
	char* pTmp = new char[ nLen + ( nLen >> 2 ) + 3 ];

	ZeroMemory( buf, 4 );
	ZeroMemory( pTmp, nLen + ( nLen >> 2 ) + 3 );

	int i = 0;
	int j = 0;

	while ( i < nLen )
	{
		if ( *( pchIn + i ) >= 0 )
		{
			pTmp[ j++ ] = pchIn[ i++ ];
		}
		else
		{
			WCHAR wch;
			GB2312ToUnicode( & wch, pchIn + i );

			UnicodeToUTF8( buf, & wch );

			unsigned short int nTmp = 0;
			nTmp = pTmp[ j     ] = buf[ 0 ];
			nTmp = pTmp[ j + 1 ] = buf[ 1 ];
			nTmp = pTmp[ j + 2 ] = buf[ 2 ];

			j += 3;
			i += 2;
		}
	}

	pTmp[ j ] = '\0';
	strOut = pTmp;
	delete [] pTmp;
}

void CCodeLib::GB2312ToUnicode( WCHAR* pwchOut, const char* pchIn )
{
	::MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pchIn, 2, pwchOut, 1 );
}

void CCodeLib::UnicodeToUTF8( char* pchOut, WCHAR* pwchIn )
{
	char* pTmp = ( char* ) pwchIn;

	pchOut[ 0 ] = ( 0xE0 | ( ( pTmp[ 1 ] & 0xF0 ) >> 4 ) );
	pchOut[ 1 ] = ( 0x80 | ( ( pTmp[ 1 ] & 0x0F ) << 2 ) ) + ( ( pTmp[ 0 ] & 0xC0 ) >> 6 );
	pchOut[ 2 ] = ( 0x80 | ( pTmp[ 0 ] & 0x3F ) );
}*/
